﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using DiscoveryLogic.DataViz.NetworkDiagram.NetworkData;

namespace DiscoveryLogic.DataViz.NetworkDiagram.LinkerControls
{
    /// <summary>
    /// 
    /// </summary>
    public partial class AddLinker : Form
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="network1"></param>
        /// <param name="memberName1"></param>
        /// <param name="network2"></param>
        /// <param name="memberName2"></param>
        /// <param name="linkerTypeName"></param>
        /// <param name="behavior"></param>
        /// <param name="attractForce"></param>
        /// <param name="repelForce"></param>
        public delegate void OnLinkerAdded(
            string network1, string memberName1, 
            string network2, string memberName2, 
            string linkerTypeName, NetworkLinkBehavior behavior,
            double attractForce, double repelForce);
        /// <summary>
        /// 
        /// </summary>
        public event OnLinkerAdded LinkerAdded;
        private readonly Graph _Graph;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="g"></param>
        public AddLinker(Graph g)
        {
            this._Graph = g;
            InitializeComponent();
        }

        private void AddLinker_Load(object sender, EventArgs e)
        {
            this.cbo_LinkBehavior.Items.Clear();
            for (int i = 0; i <= 3; i++)
            {
                NetworkLinkBehavior behavior = (NetworkLinkBehavior)i;
                this.cbo_LinkBehavior.Items.Add(behavior.ToString());
            }
            this.cbo_Linkers.Items.Clear();
            Assembly assembly = this.GetType().Assembly;
            Type[] types = assembly.GetTypes();
            foreach (Type type in types)
            {
                if (type.GetInterface(typeof(INetworkJoinCalcuator).FullName)!=null)
                {
                    this.cbo_Linkers.Items.Add(type.FullName);
                }
            }

            this.cbo_FromNetwork.Items.Clear();
            foreach(string networkName in this._Graph.Networks.Keys)
            {
                this.cbo_FromNetwork.Items.Add(networkName);
            }
            
            this.cbo_ToNetwork.Items.Clear();
            List<string> toNetworkNames = WorkspaceManager.GetAllNetworkNames();
            foreach (string networkName in toNetworkNames)
            {
                this.cbo_ToNetwork.Items.Add(networkName);
            }
        }

        

        private void cbo_ToNetwork_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.cbo_ToNetwork.SelectedIndex >= 0)
            {
                this.cbo_ToMember.Items.Clear();
                string networkName = this.cbo_ToNetwork.SelectedItem.ToString();
                Network network = Network.ReadNetwork(networkName);
                NetworkDataObject netDO = network.NetData;
                foreach (string fieldName in netDO.LinkableFields)
                {
                    this.cbo_ToMember.Items.Add(fieldName);
                }
            }
        }

        private void btn_AddLink_Click(object sender, EventArgs e)
        {
            if (this.LinkerAdded != null)
            {
                NetworkLinkBehavior behavior = (NetworkLinkBehavior)this.cbo_LinkBehavior.SelectedIndex;
                this.LinkerAdded(
                    this.cbo_FromNetwork.Text,
                    this.cbo_FromMember.Text,
                    this.cbo_ToNetwork.Text,
                    this.cbo_ToMember.Text,
                    this.cbo_Linkers.Text, behavior,
                    (double) this.num_Attract.Value,
                    (double) this.num_Repel.Value);

                this.Close();
            }
        }

        private void cbo_FromNetwork_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(this.cbo_FromNetwork.SelectedIndex>=0)
            {
                string networkName = this.cbo_FromNetwork.SelectedItem.ToString();
                this.cbo_FromMember.Items.Clear();
                Network net = this._Graph.Networks[networkName];
                NetworkDataObject netDO = net.NetData;
                foreach(string fieldName in netDO.LinkableFields)
                {
                    this.cbo_FromMember.Items.Add(fieldName);
                }
            }
        }
    }
}
